package com.kamistoat.meimeimall.meimeimallorder.web;

import com.alibaba.fastjson.JSON;
import com.kamistoat.meimeimall.common.To.EsTo.OrderListTo;
import com.kamistoat.meimeimall.common.To.memberTo.LoginSuccessTo;
import com.kamistoat.meimeimall.common.annotation.DubboAndHTTPExceptionCatch;
import com.kamistoat.meimeimall.common.annotation.LoginRequired;
import com.kamistoat.meimeimall.common.constant.AuthConstant;
import com.kamistoat.meimeimall.common.constant.DatabaseConstant;
import com.kamistoat.meimeimall.common.constant.OrderConstant;
import com.kamistoat.meimeimall.common.dubboInterface.ThirdPartyDubboInterface;
import com.kamistoat.meimeimall.common.exception.BizCodeEnum;
import com.kamistoat.meimeimall.common.exception.RRException;
import com.kamistoat.meimeimall.common.threadlocal.ThreadLocalContextHolder;
import com.kamistoat.meimeimall.common.utils.R;
import com.kamistoat.meimeimall.meimeimallorder.config.AlipayTemplate;
import com.kamistoat.meimeimall.meimeimallorder.service.OrderService;
import com.kamistoat.meimeimall.meimeimallorder.vo.OrderListVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.dubbo.config.annotation.Reference;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Api(tags = "用户订单页面")
@RestController
@RequestMapping("web")
public class OrderPageController {
    protected Logger logger = LoggerFactory.getLogger(OrderPageController.class);

    @Autowired
    AlipayTemplate alipayTemplate;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    OrderService orderService;

    @Reference
    ThirdPartyDubboInterface thirdPartyDubboInterface;

    /**
     * 获取当前用户的分页订单(ES)查询
     *
     * @return
     */
    @ApiOperation("从ES查询当前登录用户的分页订单")
    @GetMapping("/order_list_from_es")
    @LoginRequired
    @DubboAndHTTPExceptionCatch
    public R orderListFromES(
            @RequestParam(value = "searchCondition", defaultValue = "") String searchCondition,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "pageSize", defaultValue = DatabaseConstant.DEFAULT_PAGE_SIZE) Integer pageSize) {
        LoginSuccessTo loginSuccessTo = JSON.parseObject((String) ThreadLocalContextHolder.get(AuthConstant.LOGIN_USER_THREADLOCAL_NAME), LoginSuccessTo.class);

        R fromESR = thirdPartyDubboInterface.getOrderListTosFromES(loginSuccessTo.getId(), page, pageSize, searchCondition);
        if (fromESR.getCode() != 0) {
            return fromESR;
        }

        List<OrderListTo> orderListToList = JSON.parseArray((String) fromESR.get("orderListToList"), OrderListTo.class);

        return R.ok().put("orderListToList", orderListToList).put("page", page).put("pageSize", pageSize);
    }

    /**
     * 获取当前用户的所有订单(带缓)查询
     */
    @ApiOperation("带缓查询当前登录用户的所有订单")
    @GetMapping("/order_list_all")
    @LoginRequired
    @DubboAndHTTPExceptionCatch
    public R orderListAll() {
        LoginSuccessTo loginSuccessTo = JSON.parseObject((String) ThreadLocalContextHolder.get(AuthConstant.LOGIN_USER_THREADLOCAL_NAME), LoginSuccessTo.class);
        // 带缓查询
        List<OrderListVo> orderListVoList = orderService.getOrderListAll(loginSuccessTo.getId());
        return R.ok().put("orderListVoList", orderListVoList);
    }

    /**
     * 获取当前用户的分页订单(带缓)查询
     */
    @ApiOperation("带缓查询当前登录用户的分页订单")
    @GetMapping("/order_list_page")
    @LoginRequired
    @DubboAndHTTPExceptionCatch
    public R orderListPage(@RequestParam(value = "page", defaultValue = "1") Integer page,
                           @RequestParam(value = "pageSize", defaultValue = DatabaseConstant.DEFAULT_PAGE_SIZE) Integer pageSize) {
        LoginSuccessTo loginSuccessTo = JSON.parseObject((String) ThreadLocalContextHolder.get(AuthConstant.LOGIN_USER_THREADLOCAL_NAME), LoginSuccessTo.class);
        List<OrderListVo> orderListVoList = orderService.getOrderListPage(loginSuccessTo.getId(), page, pageSize);
        return R.ok().put("orderListVoList", orderListVoList).put("pageSize", pageSize).put("page", page);
    }


    /**
     * 当前登录用户查询自己的指定订单
     */
    @ApiOperation("当前登录用户查询自己的指定订单")
    @GetMapping("/order_info/{orderSn}")
    @LoginRequired
    @DubboAndHTTPExceptionCatch
    public R getOrderBySn(@PathVariable("orderSn") String orderSn) {
        LoginSuccessTo loginSuccessTo = JSON.parseObject((String) ThreadLocalContextHolder.get(AuthConstant.LOGIN_USER_THREADLOCAL_NAME), LoginSuccessTo.class);
        // 带缓查询
        OrderListVo orderListVo = orderService.getOrderBySN(loginSuccessTo.getId(), orderSn);
        if (orderListVo == null) {
            throw new RRException(BizCodeEnum.ORDER_NOT_BELONG_MEMBER.getMessage(), BizCodeEnum.ORDER_NOT_BELONG_MEMBER.getCode());
        } else {
            return R.ok().put("orderListVo", orderListVo);
        }
    }

    /**
     * 确认收货。
     *
     * @param orderSN
     * @return
     */
    @ApiOperation("当前登录用户确认收货")
    @PostMapping("/confirm_receive_order")
    @LoginRequired
    @DubboAndHTTPExceptionCatch
    public R confirmOrder(@RequestParam String orderSN) {
        LoginSuccessTo loginSuccessTo = JSON.parseObject((String) ThreadLocalContextHolder.get(AuthConstant.LOGIN_USER_THREADLOCAL_NAME), LoginSuccessTo.class);
        RLock orderStatusModifyLock = redissonClient.getLock(OrderConstant.ORDER_MODIFY_LOCK_PREFIX + orderSN);
        // 如果抢不到该订单的修改锁，则说明该订单正处于修改状态。可能是正在被其他线程支付，或者被其他动作修改
        if (!orderStatusModifyLock.tryLock()) {
            throw new RRException(BizCodeEnum.ORDER_MODIFY_LOCKED.getMessage(), BizCodeEnum.ORDER_MODIFY_LOCKED.getCode());
        } else {
            try {
                orderService.confirmOrder(loginSuccessTo.getId(), orderSN);
                return R.ok();
            } finally {
                orderStatusModifyLock.unlock();
            }
        }
    }

    /**
     * 登录用户手动取消未支付订单。手动触发释放订单的回滚。
     */
    @ApiOperation("当前登录用户未支付取消订单")
    @PostMapping("/cancel_unpay_order")
    @LoginRequired
    @DubboAndHTTPExceptionCatch
    public R cancelUnpayOrder() {
        // TODO
        return R.ok();
    }
}
